unsigned long smfn;
int pin = 0;
- page = alloc_domheap_page(NULL);
+ // Currently, we only keep pre-zero'ed pages around for use as L1's...
+ // This will change. Soon.
+ //
+ if ( psh_type == PGT_l1_shadow )
+ {
+ if ( !list_empty(&d->arch.free_shadow_frames) )
+ {
+ struct list_head *entry = d->arch.free_shadow_frames.next;
+ page = list_entry(entry, struct pfn_info, list);
+ list_del(entry);
+ perfc_decr(free_l1_pages);
+ }
+ else
+ {
+ page = alloc_domheap_page(NULL);
+ void *l1 = map_domain_mem(page_to_pfn(page) << PAGE_SHIFT);
+ memset(l1, 0, PAGE_SIZE);
+ unmap_domain_mem(l1);
+ }
+ }
+ else
+ page = alloc_domheap_page(NULL);
+
if ( unlikely(page == NULL) )
{
printk("Couldn't alloc shadow page! dom%d count=%d\n",
{
l1_pgentry_t *pl1e = map_domain_mem(smfn << PAGE_SHIFT);
int i;
+ struct pfn_info *spage = pfn_to_page(smfn);
+ u32 min_max = spage->tlbflush_timestamp;
+ int min = SHADOW_MIN(min_max);
+ int max = SHADOW_MAX(min_max);
- for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
+ for ( i = min; i <= max; i++ )
+ {
put_page_from_l1e(pl1e[i], d);
+ pl1e[i] = mk_l1_pgentry(0);
+ }
unmap_domain_mem(pl1e);
+
+ list_add(&spage->list, &d->arch.free_shadow_frames);
+ perfc_incr(free_l1_pages);
}
static void inline
page->tlbflush_timestamp = 0;
page->u.free.cpu_mask = 0;
- free_domheap_page(page);
+ if ( type != PGT_l1_shadow )
+ free_domheap_page(page);
}
static void inline
&(shadow_linear_pg_table[l1_linear_offset(va) &
~(L1_PAGETABLE_ENTRIES-1)]);
- memset(spl1e, 0, PAGE_SIZE);
-
unsigned long sl1e;
int index = l1_table_offset(va);
int min = 1, max = 0;
unsigned long *guest, *shadow, *snapshot;
int need_flush = 0, external = shadow_mode_external(d);
int unshadow;
- unsigned long min_max;
+ u32 min_max;
int min, max;
ASSERT(spin_is_locked(&d->arch.shadow_lock));
+#define PERFC_MAX_PT_UPDATES 64
+#define PERFC_PT_UPDATES_BUCKET_SIZE 3
+PERFCOUNTER_ARRAY( wpt_updates, "writable pt updates", PERFC_MAX_PT_UPDATES )
+PERFCOUNTER_ARRAY( bpt_updates, "batched pt updates", PERFC_MAX_PT_UPDATES )
+
+PERFCOUNTER_ARRAY( hypercalls, "hypercalls", NR_hypercalls )
+PERFCOUNTER_ARRAY( exceptions, "exceptions", 32 )
+
+#define VMX_PERF_EXIT_REASON_SIZE 37
+#define VMX_PERF_VECTOR_SIZE 0x20
+PERFCOUNTER_ARRAY( vmexits, "vmexits", VMX_PERF_EXIT_REASON_SIZE )
+PERFCOUNTER_ARRAY( cause_vector, "cause vector", VMX_PERF_VECTOR_SIZE )
+
PERFCOUNTER_CPU (seg_fixups, "segmentation fixups" )
PERFCOUNTER_CPU( irqs, "#interrupts" )
PERFSTATUS( shadow_l2_pages, "current # shadow L2 pages" )
PERFSTATUS( shadow_l1_pages, "current # shadow L1 pages" )
PERFSTATUS( hl2_table_pages, "current # hl2 pages" )
+PERFSTATUS( snapshot_pages, "current # fshadow snapshot pages" )
+PERFSTATUS( writable_pte_predictions, "# writable pte predictions")
+PERFSTATUS( free_l1_pages, "current # free shadow L1 pages" )
PERFCOUNTER_CPU( check_pagetable, "calls to check_pagetable" )
PERFCOUNTER_CPU( check_all_pagetables, "calls to check_all_pagetables" )
-#define PERFC_MAX_PT_UPDATES 64
-#define PERFC_PT_UPDATES_BUCKET_SIZE 3
-PERFCOUNTER_ARRAY( wpt_updates, "writable pt updates", PERFC_MAX_PT_UPDATES )
-PERFCOUNTER_ARRAY( bpt_updates, "batched pt updates", PERFC_MAX_PT_UPDATES )
-
-PERFCOUNTER_ARRAY( hypercalls, "hypercalls", NR_hypercalls )
-PERFCOUNTER_ARRAY( exceptions, "exceptions", 32 )
-
-#define VMX_PERF_EXIT_REASON_SIZE 37
-#define VMX_PERF_VECTOR_SIZE 0x20
-PERFCOUNTER_ARRAY( vmexits, "vmexits", VMX_PERF_EXIT_REASON_SIZE )
-PERFCOUNTER_ARRAY( cause_vector, "cause vector", VMX_PERF_VECTOR_SIZE )
-
-
PERFCOUNTER_CPU( shadow_hl2_table_count, "shadow_hl2_table count" )
PERFCOUNTER_CPU( shadow_set_l1e_force_map, "shadow_set_l1e forced to map l1" )
PERFCOUNTER_CPU( shadow_set_l1e_unlinked, "shadow_set_l1e found unlinked l1" )
PERFCOUNTER_CPU( shadow_invlpg_faults, "shadow_invlpg's get_user faulted")
PERFCOUNTER_CPU( unshadow_l2_count, "unpinned L2 count")
-
-/* STATUS counters do not reset when 'P' is hit */
-PERFSTATUS( snapshot_pages, "current # fshadow snapshot pages" )
-
PERFCOUNTER_CPU(shadow_status_shortcut, "fastpath miss on shadow cache")
PERFCOUNTER_CPU(shadow_status_calls, "calls to ___shadow_status" )
PERFCOUNTER_CPU(shadow_status_miss, "missed shadow cache" )
PERFCOUNTER_CPU(validate_hl2e_changes, "validate_hl2e makes changes")
PERFCOUNTER_CPU(exception_fixed, "pre-exception fixed")
PERFCOUNTER_CPU(gpfn_to_mfn_safe, "calls to gpfn_to_mfn_safe")
-PERFSTATUS( writable_pte_predictions, "# writable pte predictions")
PERFCOUNTER_CPU(remove_write_access, "calls to remove_write_access")
PERFCOUNTER_CPU(remove_write_access_easy, "easy outs of remove_write_access")
PERFCOUNTER_CPU(remove_write_no_work, "no work in remove_write_access")